package com.zsrd.self.base.config; /***
 *
 *包都在这
 *
 *
 *
 */
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;

public class WXPaySignatureCertificateUtil {









    /**
     * 保存微信平台证书
     */
    private static final ConcurrentHashMap<String, AutoUpdateCertificatesVerifier> verifierMap = new ConcurrentHashMap<>();

    /**
     * 功能描述:获取平台证书，自动更新
     * 注意：这个方法内置了平台证书的获取和返回值解密
     */
    public static AutoUpdateCertificatesVerifier getVerifier() {
        String mchSerialNo = WxV3PayConfig.mchSerialNo;
        AutoUpdateCertificatesVerifier verifier = null;
        if (verifierMap.isEmpty() || !verifierMap.containsKey(mchSerialNo)) {
            verifierMap.clear();
            try {
                //传入证书
                PrivateKey privateKey = getPrivateKey();
                //刷新
                PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey);
                WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer);
                verifier = new AutoUpdateCertificatesVerifier(credentials
                        , WxV3PayConfig.apiV3Key.getBytes("utf-8"));
                verifierMap.put(verifier.getValidCertificate().getSerialNumber()+"", verifier);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            verifier = verifierMap.get(mchSerialNo);
        }
        return verifier;
    }





    /**
     * 小程序及其它支付生成带签名支付信息
     *
     * @param timestamp 时间戳
     * @param nonceStr  随机数
     * @param prepayId  预付单
     * @return 支付信息
     * @throws Exception
     */
    public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) throws Exception {
        //上传私钥
        PrivateKey privateKey = getPrivateKey();
        String signatureStr = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId)
                .collect(Collectors.joining("\n", "", "\n"));
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(privateKey);
        sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(sign.sign());
    }


    /**
     * 获取私钥。
     * 证书路径 本地使用如： D:\\微信平台证书工具\\7.9\\apiclient_key.pem
     * 证书路径 线上使用如： /usr/apiclient_key.pem
     * String filename 私钥文件路径  (required)
     * @return 私钥对象
     */
    public static PrivateKey getPrivateKey() throws IOException {
        try {
            // 使用 ClassLoader 获取资源文件
            InputStream inputStream = WXPaySignatureCertificateUtil.class.getClassLoader().getResourceAsStream("apiclient_key.pem");
            if (inputStream == null) {
                throw new RuntimeException("无法找到资源文件: " );
            }

            // 读取私钥内容
            byte[] privateKeyBytes = new byte[inputStream.available()];
            inputStream.read(privateKeyBytes);
            String privateKeyContent = new String(privateKeyBytes, StandardCharsets.UTF_8);

            // 移除PEM格式头部和尾部，并去除空格
            String privateKey = privateKeyContent
                    .replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");

            // 创建密钥工厂实例
            KeyFactory kf = KeyFactory.getInstance("RSA");

            // 生成私钥对象
            return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的私钥规范", e);
        } catch (Exception e) {
            throw new RuntimeException("无法读取或解析私钥文件", e);
        }




//        try {
//            // 读取私钥文件内容
//            byte[] privateKeyBytes = Files.readAllBytes(Paths.get("src/main/resources/apiclient_key.pem"));
//            String privateKeyContent = new String(privateKeyBytes, "utf-8");
//
//            // 移除PEM格式头部和尾部，并去除空格
//            String privateKey = privateKeyContent
//                    .replace("-----BEGIN PRIVATE KEY-----", "")
//                    .replace("-----END PRIVATE KEY-----", "")
//                    .replaceAll("\\s+", "");
//
//            // 创建密钥工厂实例
//            KeyFactory kf = KeyFactory.getInstance("RSA");
//
//            // 生成私钥对象
//            return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
//        } catch (NoSuchAlgorithmException e) {
//            throw new RuntimeException("当前Java环境不支持RSA", e);
//        } catch (InvalidKeySpecException | IOException e) {
//            throw new RuntimeException("无法读取或解析私钥文件", e);
//        }



    }

//    public static void main(String[] args) throws IOException {
//        // 读取私钥文件并生成私钥对象
//        PrivateKey privateKey = getPrivateKey();
//        System.out.println("成功读取私钥文件并生成私钥对象");
//        // 在这里可以使用私钥进行后续的操作
//    }



}